/* vim: set ts=2 et sw=2 cindent fo=qroca: */

package com.globant.google.mendoza;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.globant.google.malbec.transport.StandAlone;
import com.globant.google.malbec.GBuy;
import com.globant.google.malbec.XmlCartEncoder;

import org.openqa.selenium.server.SeleniumServer;

/** This class inits all the components for the server to run.
 */
public final class MendozaRunner {

  /** The user entered parameters. */
  private static MendozaParameters parameters;

  /** The class logger.
   */
  private static Log log = LogFactory.getLog(MendozaRunner.class);

  /** Constructor. Creates an instance of MendozaRunner.
   *
   * @param params The mendoza parameters.
   */
  public MendozaRunner(final MendozaParameters params) {
    parameters = params;
  }

  /** Inits all the server components.
   *
   * @return Returns the server client instance.
   */
  public MendozaServerTransport init() {
    log.trace("Entering init");

    int seleniumPort = parameters.getSeleniumServerPort();
    boolean startSeleniumServer = parameters.getStartSeleniumServer();
    if (startSeleniumServer) {
      SeleniumServer selenium = null;
      try {
        selenium = new SeleniumServer(seleniumPort, false, true);
        selenium.start();
      } catch (Exception e) {
        log.debug(e.getMessage());
        log.trace("Leaving init");
        throw new RuntimeException("Unable to start selenium sever.");
      }
    }

    XmlCartEncoder encoder = new XmlCartEncoder();
    String baseURL = parameters.getBaseURL();
    String firefoxPath = parameters.getFirefoxBinPath();
    String seleniumHost = parameters.getSeleniumServerHost();
    SeleniumBuyerRobotFactory robotFactory = new SeleniumBuyerRobotFactory(
       baseURL, encoder, firefoxPath, seleniumHost, seleniumPort);

    String merchantKey = parameters.getMerchantKey();
    String merchantId = parameters.getMerchantId();
    int calculationsTimeout = parameters.getCalculationsTimeout();
    int placeOrderTimeout = parameters.getPlaceOrderTimeout();
    MendozaServer mendozaServer = new MendozaServer(
        robotFactory, merchantId, merchantKey, calculationsTimeout,
        placeOrderTimeout);
    String merchantURL = parameters.getCallbackUrl();
    if (merchantURL == null) {
      log.trace("Leaving init");
      throw new RuntimeException("merchant url cannot be null.");
    }

    int callbackPort = parameters.getMerchantPort();
    StandAlone transport = new StandAlone(null, null,
        merchantId, merchantKey, merchantURL,
        callbackPort, true);
    TransportProxy proxy = new TransportProxy(transport, mendozaServer);

    GBuy gbuy = new GBuy(proxy);
    gbuy.registerOrderListener(proxy);
    gbuy.start();

    int serverPort = parameters.getMendozaPort();
    /* The server starts to listen...*/
    MendozaServerTransport mendozaServerTransport =
      new MendozaServerTransport(mendozaServer, serverPort);
    log.trace("Leaving init");
    return mendozaServerTransport;
  }

  /** Main entry point.
   *
   * @param args Command line parameters.
   */
  public static void main(final String[] args) {
    log.trace("Entering main");
    String configFile = System.getProperty("mendoza.config.path");
    MendozaParameters params =
        MendozaParameters.generateParameters(configFile);
    MendozaRunner mendozaRunner = new MendozaRunner(params);
    mendozaRunner.init();
    System.out.println("MendozaServer server listening on port "
        + params.getMendozaPort());
    while (true) {
      // waiting for commands...
      ;
    }
  }
}
